<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <base href="/">
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="layui/css/layui.css">
    <style>
        .layui-table tr{
            height: 52px;
        }
        .layui-table-cell{
            height: 52px;
        }
    </style>
</head>
<body>
<!--数据列表-->
<table class="layui-table" lay-data="{url:'category/list', page:true, id:'datalist',toolbar:'#toptools'}" lay-filter="datalist">
    <thead>
    <tr>
        <th lay-data="{field:'id',}">ID</th>
        <th lay-data="{field:'name'}">名称</th>
        <th lay-data="{templet:'#imgTpl'}">图片</th>
        <th lay-data="{templet:'#parentTpl'}">父级分类</th>
        <th lay-data="{field:'level'}">级别</th>
        <th lay-data="{toolbar:'#linetools'}">操作</th>
    </tr>
    </thead>
</table>
<!--图片列自定义模板-->
<script type="text/html" id="imgTpl">
    <!--    src属性中就要写上当前行的imgurl属性-->
    <img src="{{d.imgurl}}" style="height: 50px;width: 50px;">
</script>
<!--父级分类自定义模板-->
<script type="text/html" id="parentTpl">
    {{#  if(d.parent_id==-1){ }}
    <span style="color: red;">顶级</span>
    {{# }else{ }}
    <span style="">{{ d.parent.name }}</span>
    {{# } }}
</script>

<!--新增数据表单-->
<div style="display:none" id="addWin" lay-filter="addWin" class="layui-form">
    <div class="layui-form-item">
        <label class="layui-form-label">父级分类</label>
        <div class="layui-input-inline">
            <select name="parent_id">
                <option value="-1">无父级分类</option>
            </select>
        </div>
    </div>
    <div class="layui-form-item">
        <label class="layui-form-label">名称</label>
        <div class="layui-input-inline">
            <input type="text" name="name" required lay-verify="required" placeholder="请输入分类名称" autocomplete="off" class="layui-input">
        </div>
    </div>
    <div class="layui-form-item">
        <label class="layui-form-label">图片</label>
        <div class="layui-input-inline">
            <img src="shopfile/img/icon/uploadimg.png" _id="addupload" style="width:100px;height:100px;cursor: pointer">
            <input type="hidden" _id="addimgurl" name="imgurl"  lay-verify="shopimg">
        </div>
    </div>
    <div class="layui-form-item"  style="text-align: center;">
        <button  type="button" lay-submit lay-filter="addsave"  class="layui-btn " id="addsave" >保存</button>
        <button type="button"  class="layui-btn " id="addcancel">取消</button>
    </div>
</div>
<!--修改对话框-->
<div style="display:none" id="editWin" lay-filter="editWin" class="layui-form">
    <input name="id" type="hidden">
    <input name="level" type="hidden">
    <div class="layui-form-item">
        <label class="layui-form-label">父级分类</label>
        <div class="layui-input-inline">
            <select name="pid">
                <option value="-1">无父级分类</option>
            </select>
        </div>
    </div>
    <div class="layui-form-item">
        <label class="layui-form-label">名称</label>
        <div class="layui-input-inline">
            <input type="text" name="name" required lay-verify="required" placeholder="请输入分类名称" autocomplete="off" class="layui-input">
        </div>
    </div>
    <div class="layui-form-item">
        <label class="layui-form-label">图片</label>
        <div class="layui-input-inline">
            <img src="shopfile/img/icon/uploadimg.png" _id="addupload" style="width:100px;height:100px;cursor: pointer">
            <input type="hidden" _id="addimgurl" name="imgurl"  lay-verify="shopimg">
        </div>
    </div>
    <div class="layui-form-item"  style="text-align: center;">
        <button  type="button" lay-submit lay-filter="editsave"  class="layui-btn " >保存</button>
        <button type="button"  class="layui-btn " id="editcancel">取消</button>
    </div>
</div>

<!--行内工具栏-->
<script id="linetools" type="text/html">
    <button  type="button"  class="layui-btn-sm layui-btn-radius " lay-event="edit" >编辑</button>
    <button type="button"  class="layui-btn-sm layui-btn-radius " lay-event="delete">删除</button>
</script>
<!--头部工具栏-->
<script id="toptools" type="text/html">
    <div class="layui-form-item">
        <div class="layui-input-inline">
            <input type="text" name="text"  placeholder="请输入查询内容" autocomplete="off" class="layui-input">
        </div>
        <div class="layui-input-inline">
            <button type="button"  class="layui-btn layui-btn-radius" lay-event="check">查询</button>
            <button type="button"  class="layui-btn layui-btn-radius" lay-event="add">新增</button>
        </div>
    </div>
</script>
<script src="layui/layui.all.js"></script>
<script>
    // 从 layui 中引入 jQuery 对象，方便后续使用 jQuery 相关方法操作 DOM
    const $ = layui.$;
    // 从 layui 中引入表格模块，用于处理表格相关操作，如表格数据加载、刷新等
    const table = layui.table;
    // 从 layui 中引入表单模块，用于处理表单数据的获取、验证、填充等操作
    const form = layui.form;
    // 从 layui 中引入弹出层模块，用于创建各种类型的弹出层，如确认框、提示框等
    const layer = layui.layer;
    // 从 layui 中引入文件上传模块，用于处理文件上传功能
    const upload = layui.upload;

    /* 监听表格行内按钮的点击事件，tool是预定义的，当点击带有 lay-event 属性的按钮时触发 */
    table.on("tool(datalist)", function (obj) {
        // 获取被点击按钮的 lay-event 属性值，用于判断点击的是哪个按钮
        let event = obj.event;
        // 获取被点击按钮所在行的数据，包含该行的所有字段信息
        let data = obj.data;
        // 判断点击的按钮是否为删除按钮
        if (event === 'delete') {
            // 弹出确认框，防止用户误操作，询问用户是否确认删除
            layer.confirm("确认要删除吗?", function () {
                // 当用户点击确认后，执行以下代码
                $.ajax({
                    // 发送删除请求的 URL，这里是删除分类的接口
                    url: 'category/delete',
                    // 发送的数据，包含要删除的分类的 ID
                    data: { id: data.id },
                    // 请求成功后的回调函数
                    success: function () {
                        // 弹出提示信息，告知用户删除成功，显示 1800 毫秒，图标为 1 表示成功
                        layer.msg("删除成功", { time: 1800, icon: 1 });
                        // 刷新表格数据，并将表格显示到第一页
                        table.reload("datalist", { page: { curr: 1 } });
                    }
                });
            });
        }
        // 判断点击的按钮是否为编辑按钮
        else if (event === 'edit') {
            // 调用 getChildren 函数，获取所有一级分类信息并填充到下拉框中
            getChildren();
            // 将当前行的数据填充到编辑表单中，实现数据回显
            form.val("editWin", data);
            // 将当前行的图片 URL 赋值给图片元素的 src 属性，实现图片回显
            $("[_id='addupload']").attr("src", data.imgurl);
            // 弹出编辑分类的弹出层，类型为页面层，设置标题、宽高和内容
            layer.open({
                type: 1,
                title: '编辑分类',
                area: ['400px', '400px'],
                content: $("#editWin")
            });
        }
    });

    // 查询出所有的一级分类，并将一级分类的信息添加到下拉框中
    function getChildren() {
        $.ajax({
            // 发送获取一级分类信息的请求的 URL
            url: "category/getChildren",
            // 发送的数据，请求 ID 为 -1 的分类信息，通常 -1 表示顶级分类
            data: { id: -1 },

            // 请求成功后的回调函数，result 为服务器返回的数据
            success: function (result) {
                // 在控制台打印服务器返回的数据，方便调试
               /* console.log(result);*/
                // 用于存储去重后的分类信息
                const uniqueCategorise = [];
                // 用于存储分类名称的集合，利用 Set 的特性实现去重
                const nameSet = new Set();
                // 遍历服务器返回的分类信息
                result.forEach(category => {
                    // 判断当前分类名称是否已经存在于集合中
                    if (!nameSet.has(category.name)) {
                        // 如果不存在，则将该分类名称添加到集合中
                        nameSet.add(category.name);
                        // 将该分类信息添加到去重后的数组中
                        uniqueCategorise.push(category);
                    }
                });
               /* console.log(uniqueCategorise)*/
                // 清空下拉框中的所有选项
                $("[name='parent_id']").empty();
                // 向下拉框中添加一个默认选项，表示无父级分类
                $("[name='parent_id']").append("<option value='-1'>无父级分类</option>");
                // 遍历服务器返回的分类信息，将每个分类信息添加到下拉框中
                for (let i = 0; i < uniqueCategorise.length; i++) {
                    $("[name='parent_id']").append("<option value='" + uniqueCategorise[i].id + "'>" + uniqueCategorise[i].name + "</option>");
                }
                // 重新渲染下拉框，使新添加的选项生效
                form.render('select');
            }
        });
    }

    /* 监听表格头部工具栏按钮的点击事件，当点击带有 lay-event 属性的按钮时触发 */
    table.on("toolbar(datalist)", function (obj) {
        // 获取被点击按钮的 lay-event 属性值，用于判断点击的是哪个按钮
        let event = obj.event;
        // 判断点击的按钮是否为新增按钮
        if (event === 'add') {
            $("#addWin [name='name']").empty();
            // 调用 getChildren 函数，获取所有一级分类信息并填充到下拉框中
            getChildren();
            // 将图片元素的 src 属性设置为默认的上传图片的 URL
            $("[_id='addupload']").attr("src", "shopfile/img/icon/uploadimg.png");
            // 弹出新增分类的弹出层，类型为页面层，设置标题、宽高和内容
            layer.open({
                type: 1,
                title: '新增分类',
                area: ['400px', '400px'],
                content: $("#addWin")
            });
        }
        // 判断点击的按钮是否为查询按钮
        else if (event === 'check') {
            // 获取输入框中的查询内容
            let text = $("[name='text']").val();
            // 重新加载表格数据，将查询内容作为参数传递给后端，并将表格显示到第一页
            table.reload("datalist", { where: { 'text': text }, page: { curr: 1 } });
            // 将输入框中的查询内容重新赋值，确保输入框内容不变
            $("[name='text']").val(text);
        }
    });

    // 初始化文件上传功能
    upload.render({
        // 指定文件上传的触发元素，这里是通过自定义属性 _id 来选择元素
        elem: "[_id='addupload']",
        // 文件上传的请求 URL
        url: "file/uploadSystemCategory",
        // 文件上传成功后的回调函数，result 为服务器返回的数据
        done: function (result) {
            // 获取服务器返回的文件 URL
            let url = result.data[0].src;
            // 将图片元素的 src 属性设置为上传成功后的文件 URL
            $("[_id='addupload']").attr("src", url);
            // 将上传成功后的文件 URL 赋值给隐藏的输入框，用于表单提交
            $("[_id='addimgurl']").val(url);
        },
        // 文件上传失败后的回调函数
        error: function () {
            // 弹出提示信息，告知用户上传失败，图标为 2 表示失败
            layer.msg("上传失败", { icon: 2 });
        }
    });

    // 监听新增表单的提交事件，当点击新增表单的保存按钮时触发
    form.on("submit(addsave)", function (data) {
        // 在控制台打印提示信息，表明表单提交并验证通过
/*        console.log("表单提交并验证通过");
        // 在控制台打印表单数据，方便调试
        console.log(data);*/
        // 发送 AJAX 请求，将表单数据提交到服务器的新增分类接口
        $.ajax({
            url: 'category/add',
            data: data.field,
            success: function (result) {
                // 关闭所有弹出层
                layer.closeAll();
                // 弹出提示信息，告知用户添加成功，显示 1800 毫秒，图标为 1 表示成功
                layer.msg("添加成功", { icon: 1, time: 1800 });
                // 刷新表格数据
                table.reload("datalist");
            }
        });
        // 阻止表单的默认提交行为，防止页面刷新
        return false;
    });

    // 监听编辑表单的提交事件，当点击编辑表单的保存按钮时触发
    form.on("submit(editsave)", function (data) {
        // 发送 AJAX 请求，将表单数据提交到服务器的编辑分类接口
        $.ajax({
            url: 'category/edit',
            data: data.field,
            success: function () {
                // 关闭所有弹出层
                layer.closeAll();
                // 弹出提示信息，告知用户编辑成功（原代码这里写的“添加成功”有误，可根据实际情况修改），显示 1800 毫秒，图标为 1 表示成功
                layer.msg("添加成功", { icon: 1, time: 1800 });
                // 刷新表格数据
                table.reload("datalist");
            }
        });
        // 阻止表单的默认提交行为，防止页面刷新
        return false;
    });

    // 监听新增表单取消按钮的点击事件，当点击取消按钮时触发
    $('#addcancel').on('click', function () {
        // 关闭所有弹出层
        layer.closeAll();
    });

    // 监听编辑表单取消按钮的点击事件，当点击取消按钮时触发
    $('#editcancel').on('click', function () {
        // 关闭所有弹出层
        layer.closeAll();
    });

    // 自定义表单验证规则，用于验证图片是否上传
    form.verify({
        shopimg: function (value, item) {
            // value 为表单组件的值，item 为对应的表单组件元素
            // 判断图片 URL 是否为空
            if (!value) {
                // 如果为空，则返回错误提示信息
                return "必须上传图片";
            }
        }
    });
</script>
</body>
</html>